package top.overstep.zboot.system.commons.shiro;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.Getter;
import lombok.Setter;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.Serializable;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Getter
@Setter
public class RedisCache<K,V> implements Cache<K,V> {

    private RedisTemplate<String,V> redisTemplate;

    private Long exprie;

    private String prefix;

    private static Gson gson;
    static{
        gson = new GsonBuilder().create();
    }

    @Override
    public V get(K k) throws CacheException {
        String key = prefix+ this.serializable(k);
        return redisTemplate.opsForValue().get(key);
    }

    @Override
    public V put(K k, V v) throws CacheException {
        String key = prefix+ this.serializable(k);
        redisTemplate.opsForValue().set(key,v,1800,TimeUnit.SECONDS);
        return get(k);

    }

    @Override
    public V remove(K k) throws CacheException {
        String key = prefix+ this.serializable(k);
        V v = get(k);
        redisTemplate.delete(key);
        return v;
    }

    @Override
    public void clear() throws CacheException {
        Set<String> keys = redisTemplate.keys(prefix + "*");
        redisTemplate.delete(keys);
    }

    @Override
    public int size() {
       return redisTemplate.keys(prefix + "*").size();
    }

    @Override
    public Set<K> keys() {
        Set keys = redisTemplate.keys(prefix + "*");
        return keys;
    }

    @Override
    public Collection<V> values() {
        Set<String> keys = redisTemplate.keys(prefix + "*");
        return redisTemplate.opsForValue().multiGet(keys);
    }

    public RedisCache() {
    }

    public RedisCache(RedisTemplate<String, V> redisTemplate, Long exprie, String prefix) {
        this.redisTemplate = redisTemplate;
        this.exprie = exprie;
        this.prefix = prefix;
    }

    public String serializable(K key){
        return gson.toJson(key);
    }
    public Object deserializable(String key){
        return gson.fromJson(key, Object.class);
    }

}
